home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / tm2ascii / source / tm2ascii.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  39KB  |  1,554 lines

  1. #include "struct.c"
  2.  
  3. #ifdef _DEBUG
  4. #define MWDEBUG 1
  5. #include "memwatch.h"
  6.  
  7. __stdargs void kputs(char *);
  8. __stdargs char kgetc(void);
  9. __stdargs void kprintf(char *,...);
  10.  
  11. #define DEBUG_PUTSTR(a) kputs(a);
  12. #define DEBUG_GETCHR    kgetc();
  13. #define DEBUG_PRINTF(a,b)  kprintf(a,b);
  14. #else
  15. #define DEBUG_PUTSTR(a)
  16. #define DEBUG_GETCHR
  17. #define DEBUG_PRINTF(a,b)
  18. #endif
  19.  
  20. #define BUFSIZE 65536
  21.  
  22. static char Version[] = "$VER: TM2Ascii 1.0   "__DATE__" "__TIME__;
  23.  
  24.  
  25. struct List ObjectLists[TMOBJTYPES];
  26.  
  27. ULONG stopchunks[]={ID_PREF,ID_TMEX,
  28.                     ID_PREF,ID_TMIM,
  29.                     ID_PREF,ID_TMSO,
  30.                     ID_PREF,ID_TMMO,
  31.                     ID_PREF,ID_TMIC,
  32.                     ID_PREF,ID_TMDO,
  33.                     ID_PREF,ID_TMAC};
  34. struct PrefHeader PrefHdrChunk={TMPREFSVERSION,0,0};
  35.  
  36. /* Exec node */
  37. struct ExecNode {
  38.                  struct Node  en_Node;
  39.                  ULONG        en_Flags;
  40.                  UWORD        en_ExecType;
  41.                  WORD         en_Priority;
  42.                  LONG         en_Delay;
  43.                  ULONG        en_Stack;
  44.                  char        *en_Command;
  45.                  char        *en_CurrentDir;
  46.                  char        *en_HotKey;
  47.                  char        *en_Output;
  48.                  char        *en_Path;
  49.                  char        *en_PubScreen;
  50.                 };
  51.  
  52. /* Image node */
  53. struct ImageNode {
  54.                   struct Node  in_Node;
  55.                   char        *in_File;
  56.                  };
  57.  
  58. /* Sound node */
  59. struct SoundNode {
  60.                   struct Node  sn_Node;
  61.                   char        *sn_Command;
  62.                   char        *sn_Port;
  63.                  };
  64.  
  65. /* Menu node */
  66. struct MenuNode {
  67.                   struct Node  mn_Node;
  68.                   char        *mn_Exec;
  69.                   char        *mn_Sound;
  70.                  };
  71.  
  72. /* Icon node */
  73. struct IconNode {
  74.                  struct Node  in_Node;
  75.                  ULONG        in_Flags;
  76.                  char        *in_Exec;
  77.                  char        *in_Image;
  78.                  char        *in_Sound;
  79.                  LONG         in_XPos;
  80.                  LONG         in_YPos;
  81.                 };
  82.  
  83. /* Dock node */
  84. struct DockNode {
  85.                  struct Node      dn_Node;
  86.                  ULONG            dn_Flags;
  87.                  char            *dn_HotKey;
  88.                  char            *dn_PubScreen;
  89.                  char            *dn_Title;
  90.                  struct TextAttr  dn_Font;
  91.                  char            *dn_FontDesc;
  92.                  LONG             dn_XPos;
  93.                  LONG             dn_YPos;
  94.                  ULONG            dn_Columns;
  95.                  struct List     *dn_ToolsList;
  96.                 };
  97.  
  98. /* Access node */
  99. struct AccessNode {
  100.                    struct Node an_Node;
  101.                    struct List an_Entries;
  102.                   };
  103.  
  104. /* Tool node */
  105. struct ToolNode {
  106.                  struct Node  tn_Node;
  107.                  char        *tn_Image;
  108.                  char        *tn_Sound;
  109.                 };
  110.  
  111. struct Node *GetHead(struct List *List)
  112. {
  113.  if (List->lh_Head->ln_Succ)
  114.   return List->lh_Head;
  115.  else
  116.   return NULL;
  117. }
  118.  
  119. struct Node *GetSucc(struct Node *Node)
  120. {
  121.  if (Node->ln_Succ->ln_Succ)
  122.   return Node->ln_Succ;
  123.  else
  124.   return NULL;
  125. }
  126.  
  127. char *GetConfigStr(UBYTE **buf)
  128. {
  129.  char *s=*buf;
  130.  char *new;
  131.  ULONG len=strlen(s)+1;
  132.  
  133.  /* Allocate string buffer */
  134.  if (new=malloc(len)) {
  135.   /* Copy string */
  136.   strcpy(new,s);
  137.  
  138.   /* Correct pointer */
  139.   *buf+=len;
  140.  }
  141.  return(new);
  142. }
  143.  
  144. /* Write one config string and correct pointer */
  145. BOOL PutConfigStr(char *s, UBYTE **buf)
  146. {
  147.  /* string valid? */
  148.  if (s) {
  149.   /* Copy string to buffer */
  150.   strcpy(*buf,s);
  151.  
  152.   /* Correct pointer */
  153.   *buf+=strlen(s)+1;
  154.   return(TRUE);
  155.  }
  156.  return(FALSE);
  157. }
  158.  
  159. /* Free exec node */
  160. void FreeExecNode(struct Node *node)
  161. {
  162.  struct ExecNode *en=(struct ExecNode *) node;
  163.  char *s;
  164.  
  165.  if (s=en->en_Node.ln_Name) free(s);
  166.  if (s=en->en_Command) free(s);
  167.  if (s=en->en_CurrentDir) free(s);
  168.  if (s=en->en_Output) free(s);
  169.  if (s=en->en_Path) free(s);
  170.  if (s=en->en_HotKey) free(s);
  171.  if (s=en->en_PubScreen) free(s);
  172.  
  173.  /* Free node */
  174.  FreeMem(en,sizeof(struct ExecNode));
  175. }
  176.  
  177. /* Free image node */
  178. void FreeImageNode(struct Node *node)
  179. {
  180.  struct ImageNode *in=(struct ImageNode *) node;
  181.  char *s;
  182.  
  183.  if (s=in->in_Node.ln_Name) free(s);
  184.  if (s=in->in_File) free(s);
  185.  
  186.  /* Free node */
  187.  FreeMem(in,sizeof(struct ImageNode));
  188. }
  189.  
  190. /* Free sound node */
  191. void FreeSoundNode(struct Node *node)
  192. {
  193.  struct SoundNode *sn=(struct SoundNode *) node;
  194.  char *s;
  195.  
  196.  if (s=sn->sn_Node.ln_Name) free(s);
  197.  if (s=sn->sn_Command) free(s);
  198.  if (s=sn->sn_Port) free(s);
  199.  
  200.  /* Free node */
  201.  FreeMem(sn,sizeof(struct SoundNode));
  202. }
  203.  
  204. /* Free menu node */
  205. void FreeMenuNode(struct Node *node)
  206. {
  207.  struct MenuNode *mn=(struct MenuNode *) node;
  208.  char *s;
  209.  
  210.  if (s=mn->mn_Node.ln_Name) free(s);
  211.  if (s=mn->mn_Exec) free(s);
  212.  if (s=mn->mn_Sound) free(s);
  213.  
  214.  /* Free node */
  215.  FreeMem(mn,sizeof(struct MenuNode));
  216. }
  217.  
  218. /* Free icon node */
  219. void FreeIconNode(struct Node *node)
  220. {
  221.  struct IconNode *in=(struct IconNode *) node;
  222.  char *s;
  223.  
  224.  if (s=in->in_Node.ln_Name) free(s);
  225.  if (s=in->in_Exec) free(s);
  226.  if (s=in->in_Image) free(s);
  227.  if (s=in->in_Sound) free(s);
  228.  
  229.  /* Free node */
  230.  FreeMem(in,sizeof(struct IconNode));
  231. }
  232.  
  233. /* Free tool list */
  234. void FreeToolsList(struct List *toollist)
  235. {
  236.  struct ToolNode *tn1,*tn2=(struct ToolNode *)GetHead(toollist);
  237.  
  238.  /* Free tool nodes */
  239.  while (tn1=tn2) {
  240.   char *s;
  241.  
  242.   /* Get next node */
  243.   tn2=(struct ToolNode *)GetSucc(tn1);
  244.  
  245.   /* Remove node */
  246.   Remove((struct Node *) tn1);
  247.  
  248.   /* Free node */
  249.   if (s=tn1->tn_Node.ln_Name) free(s);
  250.   if (s=tn1->tn_Image) free(s);
  251.   if (s=tn1->tn_Sound) free(s);
  252.   FreeMem(tn1,sizeof(struct ToolNode));
  253.  }
  254.  free(toollist);
  255. }
  256.  
  257. /* Free dock node */
  258. void FreeDockNode(struct Node *node)
  259. {
  260.  struct DockNode *dn=(struct DockNode *) node;
  261.  char *s;
  262.  
  263.  if (s=dn->dn_Node.ln_Name) free(s);
  264.  if (s=dn->dn_HotKey) free(s);
  265.  if (s=dn->dn_PubScreen) free(s);
  266.  if (s=dn->dn_Title) free(s);
  267.  if (s=dn->dn_Font.ta_Name) free(s);
  268.  if (s=dn->dn_FontDesc) free(s);
  269.  
  270.  /* Free tool list */
  271.  if (dn->dn_ToolsList) FreeToolsList(dn->dn_ToolsList);
  272.  
  273.  /* Free node */
  274.  FreeMem(dn,sizeof(struct DockNode));
  275. }
  276.  
  277. /* Free Access node */
  278. void FreeAccessNode(struct Node *node)
  279. {
  280.  struct AccessNode *an=(struct AccessNode *) node;
  281.  char *s;
  282.  
  283.  if (s=an->an_Node.ln_Name) free(s);
  284.  
  285.  /* Free entries */
  286.  {
  287.   struct Node *aen1,*aen2=GetHead(&an->an_Entries);
  288.  
  289.   /* Scan list */
  290.   while (aen1=aen2) {
  291.    /* Get next node */
  292.    aen2=GetSucc(aen1);
  293.  
  294.    /* Remove node */
  295.    Remove(aen1);
  296.  
  297.    /* Free node */
  298.    if (s=aen1->ln_Name) free(s);
  299.    FreeMem(aen1,sizeof(struct Node));
  300.   }
  301.  }
  302.  /* Free Node */
  303.  FreeMem(an,sizeof(struct AccessNode));
  304. }
  305.  
  306. /* Read TMEX IFF chunk into Exec node */
  307. struct Node *ReadExecNode(UBYTE *buf)
  308. {
  309.  struct ExecNode *en;
  310.  
  311.  /* Allocate memory for node */
  312.  if (en=AllocMem(sizeof(struct ExecNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  313.   struct ExecPrefsObject *epo=(struct ExecPrefsObject *) buf;
  314.   ULONG sbits=epo->epo_StringBits;
  315.   UBYTE *ptr=(UBYTE *) &epo[1];
  316.  
  317.   if ((!(sbits & EXPO_NAME) || (en->en_Node.ln_Name=GetConfigStr(&ptr))) &&
  318.       (!(sbits & EXPO_COMMAND) || (en->en_Command=GetConfigStr(&ptr))) &&
  319.       (!(sbits & EXPO_CURDIR) || (en->en_CurrentDir=GetConfigStr(&ptr))) &&
  320.       (!(sbits & EXPO_HOTKEY) || (en->en_HotKey=GetConfigStr(&ptr))) &&
  321.       (!(sbits & EXPO_OUTPUT) || (en->en_Output=GetConfigStr(&ptr))) &&
  322.       (!(sbits & EXPO_PATH) || (en->en_Path=GetConfigStr(&ptr))) &&
  323.       (!(sbits & EXPO_PSCREEN) || (en->en_PubScreen=GetConfigStr(&ptr)))) {
  324.    /* Copy flags & values */
  325.    en->en_Flags=epo->epo_Flags;
  326.    en->en_ExecType=epo->epo_ExecType;
  327.    en->en_Priority=epo->epo_Priority;
  328.    en->en_Delay=epo->epo_Delay;
  329.    en->en_Stack=epo->epo_Stack;
  330.  
  331.    /* All OK. */
  332.    return(en);
  333.   }
  334.  
  335.   /* Call failed */
  336.   FreeExecNode((struct Node *) en);
  337.  }
  338.  return(NULL);
  339. }
  340.  
  341. /* Write Exec node to TMEX IFF chunk */
  342. BOOL WriteExecNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  343. {
  344.  struct ExecNode *en=(struct ExecNode *) node;
  345.  struct ExecPrefsObject *epo=(struct ExecPrefsObject *) buf;
  346.  ULONG sbits=0;
  347.  UBYTE *ptr=(UBYTE *) &epo[1];
  348.  
  349.  /* Copy strings */
  350.  if (PutConfigStr(en->en_Node.ln_Name,&ptr)) sbits|=EXPO_NAME;
  351.  if (PutConfigStr(en->en_Command,&ptr)) sbits|=EXPO_COMMAND;
  352.  if (PutConfigStr(en->en_CurrentDir,&ptr)) sbits|=EXPO_CURDIR;
  353.  if (PutConfigStr(en->en_HotKey,&ptr)) sbits|=EXPO_HOTKEY;
  354.  if (PutConfigStr(en->en_Output,&ptr)) sbits|=EXPO_OUTPUT;
  355.  if (PutConfigStr(en->en_Path,&ptr)) sbits|=EXPO_PATH;
  356.  if (PutConfigStr(en->en_PubScreen,&ptr)) sbits|=EXPO_PSCREEN;
  357.  
  358.  /* set string bits */
  359.  epo->epo_StringBits=sbits;
  360.  
  361.  /* Copy flags & values */
  362.  epo->epo_Flags=en->en_Flags;
  363.  epo->epo_ExecType=en->en_ExecType;
  364.  epo->epo_Priority=en->en_Priority;
  365.  epo->epo_Delay=en->en_Delay;
  366.  epo->epo_Stack=en->en_Stack;
  367.  
  368.  /* calculate length */
  369.  sbits=ptr-buf;
  370.  
  371.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  372.  
  373.  /* Open chunk */
  374.  if (PushChunk(iff,0,ID_TMEX,sbits)) return(FALSE);
  375.  
  376.  /* Write chunk */
  377.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  378.  
  379.  /* Close chunk */
  380.  if (PopChunk(iff)) return(FALSE);
  381.  
  382.  /* All OK. */
  383.  return(TRUE);
  384. }
  385.  
  386. /* Read TMIM IFF chunk into Image node */
  387. struct Node *ReadImageNode(UBYTE *buf)
  388. {
  389.  struct ImageNode *in;
  390.  
  391.  /* Allocate memory for node */
  392.  if (in=AllocMem(sizeof(struct ImageNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  393.   struct ImagePrefsObject *ipo=(struct ImagePrefsObject *) buf;
  394.   ULONG sbits=ipo->ipo_StringBits;
  395.   UBYTE *ptr=(UBYTE *) &ipo[1];
  396.  
  397.   if ((!(sbits & IMPO_NAME) || (in->in_Node.ln_Name=GetConfigStr(&ptr))) &&
  398.       (!(sbits & IMPO_FILE) || (in->in_File=GetConfigStr(&ptr))))
  399.    /* All OK. */
  400.    return(in);
  401.  
  402.   /* Call failed */
  403.   FreeImageNode((struct Node *) in);
  404.  }
  405.  return(NULL);
  406. }
  407.  
  408. /* Write Image node to TMIM IFF chunk */
  409. BOOL WriteImageNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  410. {
  411.  struct ImageNode *in=(struct ImageNode *) node;
  412.  struct ImagePrefsObject *ipo=(struct ImagePrefsObject *) buf;
  413.  ULONG sbits=0;
  414.  UBYTE *ptr=(UBYTE *) &ipo[1];
  415.  
  416.  /* Copy strings */
  417.  if (PutConfigStr(in->in_Node.ln_Name,&ptr)) sbits|=IMPO_NAME;
  418.  if (PutConfigStr(in->in_File,&ptr)) sbits|=IMPO_FILE;
  419.  
  420.  /* set string bits */
  421.  ipo->ipo_StringBits=sbits;
  422.  
  423.  /* calculate length */
  424.  sbits=ptr-buf;
  425.  
  426.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  427.  
  428.  /* Open chunk */
  429.  if (PushChunk(iff,0,ID_TMIM,sbits)) return(FALSE);
  430.  
  431.  /* Write chunk */
  432.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  433.  
  434.  /* Close chunk */
  435.  if (PopChunk(iff)) return(FALSE);
  436.  
  437.  /* All OK. */
  438.  return(TRUE);
  439. }
  440.  
  441. /* Read TMSO IFF chunk into Sound node */
  442. struct Node *ReadSoundNode(UBYTE *buf)
  443. {
  444.  struct SoundNode *sn;
  445.  
  446.  /* Allocate memory for node */
  447.  if (sn=AllocMem(sizeof(struct SoundNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  448.   struct SoundPrefsObject *spo=(struct SoundPrefsObject *) buf;
  449.   ULONG sbits=spo->spo_StringBits;
  450.   UBYTE *ptr=(UBYTE *) &spo[1];
  451.  
  452.   if ((!(sbits & SOPO_NAME) || (sn->sn_Node.ln_Name=GetConfigStr(&ptr))) &&
  453.       (!(sbits & SOPO_COMMAND) || (sn->sn_Command=GetConfigStr(&ptr))) &&
  454.       (!(sbits & SOPO_PORT) || (sn->sn_Port=GetConfigStr(&ptr))))
  455.    /* All OK. */
  456.    return(sn);
  457.  
  458.   /* Call failed */
  459.   FreeSoundNode((struct Node *) sn);
  460.  }
  461.  return(NULL);
  462. }
  463.  
  464. /* Write Sound node to TMSO IFF chunk */
  465. BOOL WriteSoundNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  466. {
  467.  struct SoundNode *sn=(struct SoundNode *) node;
  468.  struct SoundPrefsObject *spo=(struct SoundPrefsObject *) buf;
  469.  ULONG sbits=0;
  470.  UBYTE *ptr=(UBYTE *) &spo[1];
  471.  
  472.  /* Copy strings */
  473.  if (PutConfigStr(sn->sn_Node.ln_Name,&ptr)) sbits|=SOPO_NAME;
  474.  if (PutConfigStr(sn->sn_Command,&ptr)) sbits|=SOPO_COMMAND;
  475.  if (PutConfigStr(sn->sn_Port,&ptr)) sbits|=SOPO_PORT;
  476.  
  477.  /* set string bits */
  478.  spo->spo_StringBits=sbits;
  479.  
  480.  /* calculate length */
  481.  sbits=ptr-buf;
  482.  
  483.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  484.  
  485.  /* Open chunk */
  486.  if (PushChunk(iff,0,ID_TMSO,sbits)) return(FALSE);
  487.  
  488.  /* Write chunk */
  489.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  490.  
  491.  /* Close chunk */
  492.  if (PopChunk(iff)) return(FALSE);
  493.  
  494.  /* All OK. */
  495.  return(TRUE);
  496. }
  497.  
  498. /* Read TMMO IFF chunk into Menu node */
  499. struct Node *ReadMenuNode(UBYTE *buf)
  500. {
  501.  struct MenuNode *mn;
  502.  
  503.  /* Allocate memory for node */
  504.  if (mn=AllocMem(sizeof(struct MenuNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  505.   struct MenuPrefsObject *mpo=(struct MenuPrefsObject *) buf;
  506.   ULONG sbits=mpo->mpo_StringBits;
  507.   UBYTE *ptr=(UBYTE *) &mpo[1];
  508.  
  509.   if ((!(sbits & MOPO_NAME) || (mn->mn_Node.ln_Name=GetConfigStr(&ptr))) &&
  510.       (!(sbits & MOPO_EXEC) || (mn->mn_Exec=GetConfigStr(&ptr))) &&
  511.       (!(sbits & MOPO_SOUND) || (mn->mn_Sound=GetConfigStr(&ptr))))
  512.    /* All OK. */
  513.    return(mn);
  514.  
  515.   /* Call failed */
  516.   FreeMenuNode((struct Node *) mn);
  517.  }
  518.  return(NULL);
  519. }
  520.  
  521. /* Write Menu node to TMMO IFF chunk */
  522. BOOL WriteMenuNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  523. {
  524.  struct MenuNode *mn=(struct MenuNode *) node;
  525.  struct MenuPrefsObject *mpo=(struct MenuPrefsObject *) buf;
  526.  ULONG sbits=0;
  527.  UBYTE *ptr=(UBYTE *) &mpo[1];
  528.  
  529.  /* Copy strings */
  530.  if (PutConfigStr(mn->mn_Node.ln_Name,&ptr)) sbits|=MOPO_NAME;
  531.  if (PutConfigStr(mn->mn_Exec,&ptr)) sbits|=MOPO_EXEC;
  532.  if (PutConfigStr(mn->mn_Sound,&ptr)) sbits|=MOPO_SOUND;
  533.  
  534.  /* set string bits */
  535.  mpo->mpo_StringBits=sbits;
  536.  
  537.  /* calculate length */
  538.  sbits=ptr-buf;
  539.  
  540.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  541.  
  542.  /* Open chunk */
  543.  if (PushChunk(iff,0,ID_TMMO,sbits)) return(FALSE);
  544.  
  545.  /* Write chunk */
  546.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  547.  
  548.  /* Close chunk */
  549.  if (PopChunk(iff)) return(FALSE);
  550.  
  551.  /* All OK. */
  552.  return(TRUE);
  553. }
  554.  
  555. /* Read TMIC IFF chunk into Icon node */
  556. struct Node *ReadIconNode(UBYTE *buf)
  557. {
  558.  struct IconNode *in;
  559.  
  560.  /* Allocate memory for node */
  561.  if (in=AllocMem(sizeof(struct IconNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  562.   struct IconPrefsObject *ipo=(struct IconPrefsObject *) buf;
  563.   ULONG sbits=ipo->ipo_StringBits;
  564.   UBYTE *ptr=(UBYTE *) &ipo[1];
  565.  
  566.   if ((!(sbits & ICPO_NAME) || (in->in_Node.ln_Name=GetConfigStr(&ptr))) &&
  567.       (!(sbits & ICPO_EXEC) || (in->in_Exec=GetConfigStr(&ptr))) &&
  568.       (!(sbits & ICPO_IMAGE) || (in->in_Image=GetConfigStr(&ptr))) &&
  569.       (!(sbits & ICPO_SOUND) || (in->in_Sound=GetConfigStr(&ptr)))) {
  570.    /* Copy flags & values */
  571.    in->in_Flags=ipo->ipo_Flags;
  572.    in->in_XPos=ipo->ipo_XPos;
  573.    in->in_YPos=ipo->ipo_YPos;
  574.  
  575.    /* All OK. */
  576.    return(in);
  577.   }
  578.  
  579.   /* Call failed */
  580.   FreeIconNode((struct Node *) in);
  581.  }
  582.  return(NULL);
  583. }
  584.  
  585. /* Write Icon node to TMIC IFF chunk */
  586. BOOL WriteIconNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  587. {
  588.  struct IconNode *in=(struct IconNode *) node;
  589.  struct IconPrefsObject *ipo=(struct IconPrefsObject *) buf;
  590.  ULONG sbits=0;
  591.  UBYTE *ptr=(UBYTE *) &ipo[1];
  592.  
  593.  /* Copy strings */
  594.  if (PutConfigStr(in->in_Node.ln_Name,&ptr)) sbits|=ICPO_NAME;
  595.  if (PutConfigStr(in->in_Exec,&ptr)) sbits|=ICPO_EXEC;
  596.  if (PutConfigStr(in->in_Image,&ptr)) sbits|=ICPO_IMAGE;
  597.  if (PutConfigStr(in->in_Sound,&ptr)) sbits|=ICPO_SOUND;
  598.  
  599.  /* set string bits */
  600.  ipo->ipo_StringBits=sbits;
  601.  
  602.  /* Copy flags & values */
  603.  ipo->ipo_Flags=in->in_Flags;
  604.  ipo->ipo_XPos=in->in_XPos;
  605.  ipo->ipo_YPos=in->in_YPos;
  606.  
  607.  /* calculate length */
  608.  sbits=ptr-buf;
  609.  
  610.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  611.  
  612.  /* Open chunk */
  613.  if (PushChunk(iff,0,ID_TMIC,sbits)) return(FALSE);
  614.  
  615.  /* Write chunk */
  616.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  617.  
  618.  /* Close chunk */
  619.  if (PopChunk(iff)) return(FALSE);
  620.  
  621.  /* All OK. */
  622.  return(TRUE);
  623. }
  624.  
  625. /* Read TMDO IFF chunk into Dock node */
  626. struct Node *ReadDockNode(UBYTE *buf)
  627. {
  628.  struct DockNode *dn;
  629.  
  630.  /* Allocate memory for node */
  631.  if (dn=AllocMem(sizeof(struct DockNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  632.   struct DockPrefsObject *dpo=(struct DockPrefsObject *) buf;
  633.   ULONG sbits=dpo->dpo_StringBits;
  634.   UBYTE *ptr=(UBYTE *) &dpo[1];
  635.   struct List *toolslist;
  636.  
  637.   if ((!(sbits & DOPO_NAME) || (dn->dn_Node.ln_Name=GetConfigStr(&ptr))) &&
  638.       (!(sbits & DOPO_HOTKEY) || (dn->dn_HotKey=GetConfigStr(&ptr))) &&
  639.       (!(sbits & DOPO_PSCREEN) || (dn->dn_PubScreen=GetConfigStr(&ptr))) &&
  640.       (!(sbits & DOPO_TITLE) || (dn->dn_Title=GetConfigStr(&ptr))) &&
  641.       (!(sbits & DOPO_FONTNAME) || (dn->dn_Font.ta_Name=GetConfigStr(&ptr))) &&
  642.       (toolslist=malloc(sizeof(struct List)))) {
  643.    LONG tools=0;
  644.    UBYTE tlflags;
  645.  
  646.    /* Init list */
  647.    NewList(toolslist);
  648.    dn->dn_ToolsList=toolslist;
  649.  
  650.    /* Get tools */
  651.    while ((tlflags=*ptr++) & DOPOT_CONTINUE) {
  652.     struct ToolNode *tn;
  653.  
  654.     if (tn=AllocMem(sizeof(struct ToolNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  655.      /* Add tool to list */
  656.      AddTail(toolslist,(struct Node *) tn);
  657.  
  658.      if ((!(tlflags & DOPOT_EXEC) || (tn->tn_Node.ln_Name=
  659.                                        GetConfigStr(&ptr))) &&
  660.          (!(tlflags & DOPOT_IMAGE) || (tn->tn_Image=GetConfigStr(&ptr))) &&
  661.          (!(tlflags & DOPOT_SOUND) || (tn->tn_Sound=GetConfigStr(&ptr))))
  662.       /* All OK. */
  663.       tools++;
  664.      else {
  665.       /* Error */
  666.       tools=-1;
  667.       break;
  668.      }
  669.     } else {
  670.      /* No memory. */
  671.      tools=-1;
  672.      break;
  673.     }
  674.    }
  675.  
  676.    /* Error? */
  677.    if (tools!=-1) {
  678.     /* Got tools? */
  679.     if (tools==0) {
  680.      /* No, free list structure */
  681.      free(toolslist);
  682.      dn->dn_ToolsList=NULL;
  683.     }
  684.  
  685.     /* Copy flags & values */
  686.     dn->dn_Flags=dpo->dpo_Flags;
  687.     dn->dn_XPos=dpo->dpo_XPos;
  688.     dn->dn_YPos=dpo->dpo_YPos;
  689.     dn->dn_Columns=dpo->dpo_Columns;
  690.     dn->dn_Font.ta_YSize=dpo->dpo_Font.ta_YSize;
  691.     dn->dn_Font.ta_Style=dpo->dpo_Font.ta_Style;
  692.     dn->dn_Font.ta_Flags=dpo->dpo_Font.ta_Flags;
  693.  
  694.     /* All OK. */
  695.     return(dn);
  696.    }
  697.   }
  698.  
  699.   /* Call failed */
  700.   FreeDockNode((struct Node *) dn);
  701.  }
  702.  return(NULL);
  703. }
  704.  
  705. /* Write Dock node to TMDO IFF chunk */
  706. BOOL WriteDockNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  707. {
  708.  struct DockNode *dn=(struct DockNode *) node;
  709.  struct DockPrefsObject *dpo=(struct DockPrefsObject *) buf;
  710.  ULONG sbits=0;
  711.  UBYTE *ptr=(UBYTE *) &dpo[1];
  712.  
  713.  /* Copy strings */
  714.  if (PutConfigStr(dn->dn_Node.ln_Name,&ptr)) sbits|=DOPO_NAME;
  715.  if (PutConfigStr(dn->dn_HotKey,&ptr)) sbits|=DOPO_HOTKEY;
  716.  if (PutConfigStr(dn->dn_PubScreen,&ptr)) sbits|=DOPO_PSCREEN;
  717.  if (PutConfigStr(dn->dn_Title,&ptr)) sbits|=DOPO_TITLE;
  718.  if (PutConfigStr(dn->dn_Font.ta_Name,&ptr)) sbits|=DOPO_FONTNAME;
  719.  
  720.  /* set string bits */
  721.  dpo->dpo_StringBits=sbits;
  722.  
  723.  /* Write tool list */
  724.  if (dn->dn_ToolsList) {
  725.   struct ToolNode *tn=(struct ToolNode *)GetHead(dn->dn_ToolsList);
  726.  
  727.   while (tn) {
  728.    UBYTE *flptr=ptr++;
  729.    UBYTE tfl=DOPOT_CONTINUE;
  730.  
  731.    if (PutConfigStr(tn->tn_Node.ln_Name,&ptr)) tfl|=DOPOT_EXEC;
  732.    if (PutConfigStr(tn->tn_Image,&ptr)) tfl|=DOPOT_IMAGE;
  733.    if (PutConfigStr(tn->tn_Sound,&ptr)) tfl|=DOPOT_SOUND;
  734.  
  735.    /* Put flags */
  736.    *flptr=tfl;
  737.  
  738.    /* Get next node */
  739.    tn=(struct ToolNode *)GetSucc(tn);
  740.   }
  741.  }
  742.  
  743.  /* Append terminator */
  744.  *ptr++=0;
  745.  
  746.  /* Copy flags & values */
  747.  dpo->dpo_Flags=dn->dn_Flags;
  748.  dpo->dpo_XPos=dn->dn_XPos;
  749.  dpo->dpo_YPos=dn->dn_YPos;
  750.  dpo->dpo_Columns=dn->dn_Columns;
  751.  dpo->dpo_Font.ta_YSize=dn->dn_Font.ta_YSize;
  752.  dpo->dpo_Font.ta_Style=dn->dn_Font.ta_Style;
  753.  dpo->dpo_Font.ta_Flags=dn->dn_Font.ta_Flags;
  754.  
  755.  /* calculate length */
  756.  sbits=ptr-buf;
  757.  
  758.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  759.  
  760.  /* Open chunk */
  761.  if (PushChunk(iff,0,ID_TMDO,sbits)) return(FALSE);
  762.  
  763.  /* Write chunk */
  764.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  765.  
  766.  /* Close chunk */
  767.  if (PopChunk(iff)) return(FALSE);
  768.  
  769.  /* All OK. */
  770.  return(TRUE);
  771. }
  772.  
  773. /* Read TMAC IFF chunk into Access node */
  774. struct Node *ReadAccessNode(UBYTE *buf)
  775. {
  776.  struct AccessNode *an;
  777.  
  778.  /* Allocate memory for node */
  779.  if (an=AllocMem(sizeof(struct AccessNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  780.   struct AccessPrefsObject *apo=(struct AccessPrefsObject *) buf;
  781.   ULONG sbits=apo->apo_StringBits;
  782.   UBYTE *ptr=(UBYTE *) &apo[1];
  783.  
  784.   if (!(sbits & DOPO_NAME) || (an->an_Node.ln_Name=GetConfigStr(&ptr))) {
  785.    LONG entries=0;
  786.    UBYTE enflags;
  787.  
  788.    /* Init list */
  789.    NewList(&an->an_Entries);
  790.  
  791.    /* Get tools */
  792.    while ((enflags=*ptr++) & AOPOE_CONTINUE) {
  793.     struct Node *aen;
  794.  
  795.     if (aen=AllocMem(sizeof(struct Node),MEMF_PUBLIC|MEMF_CLEAR)) {
  796.      /* Add tool to list */
  797.      AddTail(&an->an_Entries,aen);
  798.  
  799.      if (!(enflags & AOPOE_EXEC) || (aen->ln_Name=GetConfigStr(&ptr)))
  800.       /* All OK. */
  801.       entries++;
  802.      else {
  803.       /* Error */
  804.       entries=-1;
  805.       break;
  806.      }
  807.     } else {
  808.      /* No memory. */
  809.      entries=-1;
  810.      break;
  811.     }
  812.    }
  813.  
  814.    /* Error? All OK. */
  815.    if (entries!=-1) return(an);
  816.   }
  817.  
  818.   /* Call failed */
  819.   FreeAccessNode((struct Node *) an);
  820.  }
  821.  return(NULL);
  822. }
  823.  
  824. /* Write Access node to TMAC IFF chunk */
  825. BOOL WriteAccessNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  826. {
  827.  struct AccessNode *an=(struct AccessNode *) node;
  828.  struct AccessPrefsObject *apo=(struct AccessPrefsObject *) buf;
  829.  ULONG sbits=0;
  830.  UBYTE *ptr=(UBYTE *) &apo[1];
  831.  
  832.  /* Copy strings */
  833.  if (PutConfigStr(an->an_Node.ln_Name,&ptr)) sbits|=AOPO_NAME;
  834.  
  835.  /* set string bits */
  836.  apo->apo_StringBits=sbits;
  837.  
  838.  /* Write entry list */
  839.  {
  840.   struct Node *aen=GetHead(&an->an_Entries);
  841.  
  842.   while (aen) {
  843.    UBYTE *flptr=ptr++;
  844.    UBYTE aefl=AOPOE_CONTINUE;
  845.  
  846.    if (PutConfigStr(aen->ln_Name,&ptr)) aefl|=AOPOE_EXEC;
  847.  
  848.    /* Put flags */
  849.    *flptr=aefl;
  850.  
  851.    /* Get next node */
  852.    aen=GetSucc(aen);
  853.   }
  854.  }
  855.  
  856.  /* Append terminator */
  857.  *ptr++=0;
  858.  
  859.  /* calculate length */
  860.  sbits=ptr-buf;
  861.  
  862.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  863.  
  864.  /* Open chunk */
  865.  if (PushChunk(iff,0,ID_TMAC,sbits)) return(FALSE);
  866.  
  867.  /* Write chunk */
  868.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  869.  
  870.  /* Close chunk */
  871.  if (PopChunk(iff)) return(FALSE);
  872.  
  873.  /* All OK. */
  874.  return(TRUE);
  875. }
  876.  
  877. /* Function tables */
  878. ReadNodeFuncPtr ReadNodeFunctions[TMOBJTYPES]={
  879.                                                ReadExecNode,
  880.                                                ReadImageNode,
  881.                                                ReadSoundNode,
  882.                                                ReadMenuNode,
  883.                                                ReadIconNode,
  884.                                                ReadDockNode,
  885.                                                ReadAccessNode
  886.                                               };
  887.  
  888. WriteNodeFuncPtr WriteNodeFunctions[TMOBJTYPES]={
  889.                                                  WriteExecNode,
  890.                                                  WriteImageNode,
  891.                                                  WriteSoundNode,
  892.                                                  WriteMenuNode,
  893.                                                  WriteIconNode,
  894.                                                  WriteDockNode,
  895.                                                  WriteAccessNode
  896.                                                 };
  897.  
  898. FreeNodeFuncPtr FreeNodeFunctions[TMOBJTYPES]={FreeExecNode,
  899.                                                FreeImageNode,
  900.                                                FreeSoundNode,
  901.                                                FreeMenuNode,
  902.                                                FreeIconNode,
  903.                                                FreeDockNode,
  904.                                                FreeAccessNode};
  905.  
  906. /* Read config file */
  907.  
  908. BOOL ReadConfigFile(char *filename)
  909. {
  910.  UBYTE *configbuf;
  911.  BOOL rc=FALSE;
  912.  
  913.  DEBUG_PRINTF("read config from '%s'\n",filename);
  914.  
  915.  /* Allocate memory for config buffer */
  916.  if (configbuf=malloc(BUFSIZE)) {
  917.   struct IFFHandle *iff;
  918.  
  919.   DEBUG_PRINTF("config buffer: 0x%08lx\n",configbuf)
  920.  
  921.   /* Allocate IFF handle */
  922.   if (iff=AllocIFF()) {
  923.    /* Every error will be ignored after this point! */
  924.    rc=TRUE;
  925.  
  926.    DEBUG_PRINTF("IFF Handle: 0x%08lx\n",iff);
  927.  
  928.    /* Open IFF File */
  929.    if (iff->iff_Stream=Open(filename,MODE_OLDFILE)) {
  930.     /* Init IFF handle */
  931.     InitIFFasDOS(iff);
  932.  
  933.     DEBUG_PRINTF("IFF Stream: 0x%08lx\n",iff->iff_Stream);
  934.  
  935.     /* Open IFF handle */
  936.     if (!OpenIFF(iff,IFFF_READ)) {
  937.  
  938.      DEBUG_PUTSTR("IFF open\n");
  939.  
  940.      /* Start IFF parsing */
  941.      if (!ParseIFF(iff,IFFPARSE_STEP)) {
  942.       struct ContextNode *cn;
  943.  
  944.       DEBUG_PUTSTR("First IFF scan step\n");
  945.  
  946.       /* Check IFF type and set IFF chunk types */
  947.       if ((cn=CurrentChunk(iff)) && (cn->cn_ID==ID_FORM) &&
  948.           (cn->cn_Type==ID_PREF) &&
  949.           !PropChunk(iff,ID_PREF,ID_PRHD) &&
  950.           !StopChunks(iff,stopchunks,TMOBJTYPES) &&
  951.           !StopOnExit(iff,ID_PREF,ID_FORM) &&
  952.           !ParseIFF(iff,IFFPARSE_SCAN)) {
  953.        /* First stop chunk encountered */
  954.        struct StoredProperty *sp;
  955.  
  956.        /* Get pointer to PRHD chunk */
  957.        if (sp=FindProp(iff,ID_PREF,ID_PRHD)) {
  958.         struct PrefHeader *ph=(struct PrefHeader *) sp->sp_Data;
  959.  
  960.         /* Check file version number */
  961.         if (ph->ph_Version==TMPREFSVERSION) {
  962.  
  963.          /* Parse IFF chunks */
  964.          do {
  965.           /* Get current chunk */
  966.           if (cn=CurrentChunk(iff)) {
  967.            LONG type;
  968.  
  969.            DEBUG_PRINTF("chunk ID: 0x%08lx",cn->cn_ID);
  970.            DEBUG_PRINTF(" size: 0x%08lx",cn->cn_Size);
  971.  
  972.            /* Read IFF chunk according to chunk ID */
  973.            switch(cn->cn_ID) {
  974.             case ID_TMEX: type=TMOBJTYPE_EXEC;
  975.                           break;
  976.             case ID_TMIM: type=TMOBJTYPE_IMAGE;
  977.                           break;
  978.             case ID_TMSO: type=TMOBJTYPE_SOUND;
  979.                           break;
  980.             case ID_TMMO: type=TMOBJTYPE_MENU;
  981.                           break;
  982.             case ID_TMIC: type=TMOBJTYPE_ICON;
  983.                           break;
  984.             case ID_TMDO: type=TMOBJTYPE_DOCK;
  985.                           break;
  986.             case ID_TMAC: type=TMOBJTYPE_ACCESS;
  987.                           break;
  988.             default:      type=-1;
  989.                           break;
  990.            }
  991.  
  992.            DEBUG_PRINTF(" type: %ld\n",type);
  993.  
  994.            /* valid type? */
  995.            if (type!=-1) {
  996.             ULONG size=cn->cn_Size;
  997.  
  998.             /* Read chunk */
  999.             if (ReadChunkBytes(iff,configbuf,size)==size) {
  1000.              struct Node *node;
  1001.  
  1002.              DEBUG_PUTSTR("chunk read\n");
  1003.  
  1004.              /* Interpret chunk contents */
  1005.              if (node=(*ReadNodeFunctions[type])(configbuf)) {
  1006.  
  1007.               DEBUG_PRINTF("new node: 0x%08lx\n",node);
  1008.  
  1009.               /* Make sure ln_Name is valid */
  1010.               if (!node->ln_Name) node->ln_Name=strdup("");
  1011.  
  1012.               /* Append new node to list */
  1013.               AddTail(&ObjectLists[type],node);
  1014.              }
  1015.             }
  1016.            }
  1017.           }
  1018.          /* Next parse step */
  1019.          } while (!ParseIFF(iff,IFFPARSE_SCAN));
  1020.         }
  1021.        }
  1022.       }
  1023.      }
  1024.      CloseIFF(iff);
  1025.     }
  1026.     Close(iff->iff_Stream);
  1027.    }
  1028.    FreeIFF(iff);
  1029.   }
  1030.   free(configbuf);
  1031.  }
  1032.  return(rc);
  1033. }
  1034.  
  1035. /* Write config file */
  1036. BOOL WriteConfigFile(char *filename)
  1037. {
  1038.  UBYTE *configbuf;
  1039.  BOOL rc=FALSE;
  1040.  
  1041.  DEBUG_PRINTF("write config to '%s'\n",filename);
  1042.  
  1043.  /* Allocate memory for config buffer */
  1044.  if (configbuf=malloc(BUFSIZE)) {
  1045.   struct IFFHandle *iff;
  1046.  
  1047.   DEBUG_PRINTF("config buffer: 0x%08lx\n",configbuf)
  1048.  
  1049.   /* Allocate IFF handle */
  1050.   if (iff=AllocIFF()) {
  1051.  
  1052.    DEBUG_PRINTF("IFF Handle: 0x%08lx\n",iff);
  1053.  
  1054.    /* Open IFF File */
  1055.    if (iff->iff_Stream=Open(filename,MODE_NEWFILE)) {
  1056.     /* Init IFF handle */
  1057.     InitIFFasDOS(iff);
  1058.  
  1059.     DEBUG_PRINTF("IFF Stream: 0x%08lx\n",iff->iff_Stream);
  1060.  
  1061.     /* Open IFF handle */
  1062.     if (!OpenIFF(iff,IFFF_WRITE)) {
  1063.  
  1064.      DEBUG_PUTSTR("IFF open\n");
  1065.  
  1066.      /* Push FORM IFF chunk */
  1067.      if (!PushChunk(iff,ID_PREF,ID_FORM,IFFSIZE_UNKNOWN)) {
  1068.  
  1069.       /* Write PRHD IFF chunk */
  1070.       if (!PushChunk(iff,0,ID_PRHD,sizeof(struct PrefHeader)) &&
  1071.           (WriteChunkBytes(iff,(UBYTE *) &PrefHdrChunk,
  1072.                            sizeof(struct PrefHeader))
  1073.                             ==sizeof(struct PrefHeader)) &&
  1074.           !PopChunk(iff))
  1075.        /* Set return code */
  1076.        rc=TRUE;
  1077.  
  1078.       /* error? */
  1079.       if (rc) {
  1080.        ULONG i;
  1081.  
  1082.        /* No, scan all object lists */
  1083.        for (i=0; (i<TMOBJTYPES) && rc; i++) {
  1084.         struct Node *node=GetHead(&ObjectLists[i]);
  1085.         WriteNodeFuncPtr wnfp=WriteNodeFunctions[i];
  1086.  
  1087.         /* Scan list */
  1088.         while (node && rc) {
  1089.          /* Convert node into IFF chunk */
  1090.          rc=(*wnfp)(iff,configbuf,node);
  1091.  
  1092.          /* Get next node */
  1093.          node=GetSucc(node);
  1094.         }
  1095.        }
  1096.       }
  1097.      }
  1098.      CloseIFF(iff);
  1099.     }
  1100.     Close(iff->iff_Stream);
  1101.  
  1102.     /* Clear execution flag */
  1103.     SetProtection(filename,FIBF_EXECUTE);
  1104.    }
  1105.    FreeIFF(iff);
  1106.   }
  1107.   free(configbuf);
  1108.  }
  1109.  return(rc);
  1110. }
  1111.  
  1112. /* Free all preferences objects */
  1113. void FreeAllObjects(void)
  1114. {
  1115.  int i;
  1116.  
  1117.  for (i=0; i<TMOBJTYPES; i++) {
  1118.   struct List *list=&ObjectLists[i];
  1119.   FreeNodeFuncPtr freefunc=FreeNodeFunctions[i];
  1120.   struct Node *node;
  1121.  
  1122.   /* Scan list and free nodes */
  1123.   while (node=RemHead(list)) (*freefunc)(node);
  1124.  }
  1125. }
  1126.  
  1127. void WriteAscii(char *FileName)
  1128. {
  1129.  FILE *f;
  1130.  
  1131.  if (f = fopen(FileName, "w"))
  1132.   {
  1133.    struct Node *Node;
  1134.  
  1135.    fprintf(f, "Exec Objects\n");
  1136.    for(Node = ObjectLists[TMOBJTYPE_EXEC].lh_Head; Node->ln_Succ; Node = Node->ln_Succ)
  1137.     {
  1138.      struct ExecNode *en = (struct ExecNode *)Node;
  1139.  
  1140.      fprintf(f, "%s\n", Node->ln_Name);
  1141.      fprintf(f, "%lu %ld %d %ld %lu\n", en->en_Flags, en->en_ExecType, en->en_Priority,
  1142.                                     en->en_Delay, en->en_Stack);
  1143.      fprintf(f, "%s\n%s\n%s\n%s\n%s\n%s\n", en->en_Command, en->en_CurrentDir,
  1144.                                         en->en_HotKey, en->en_Output,
  1145.                                             en->en_Path, en->en_PubScreen);
  1146.     }
  1147.    fprintf(f, "---\n");
  1148.  
  1149.    fprintf(f, "Image Objects\n");
  1150.    for(Node = ObjectLists[TMOBJTYPE_IMAGE].lh_Head; Node->ln_Succ; Node = Node->ln_Succ)
  1151.     {
  1152.      struct ImageNode *in = (struct ImageNode *)Node;
  1153.      
  1154.      fprintf(f, "%s\n", Node->ln_Name);
  1155.      fprintf(f, "%s\n", in->in_File);
  1156.     }
  1157.    fprintf(f, "---\n");
  1158.    
  1159.    fprintf(f, "Sound Objects\n");
  1160.    for(Node = ObjectLists[TMOBJTYPE_SOUND].lh_Head; Node->ln_Succ; Node = Node->ln_Succ)
  1161.     {
  1162.      struct SoundNode *sn = (struct SoundNode *)Node;
  1163.      
  1164.      fprintf(f, "%s\n", Node->ln_Name);
  1165.      fprintf(f, "%s\n", sn->sn_Command);
  1166.      fprintf(f, "%s\n", sn->sn_Port);
  1167.     }
  1168.    fprintf(f, "---\n");
  1169.    
  1170.    fprintf(f, "Menu Objects\n");
  1171.    for(Node = ObjectLists[TMOBJTYPE_MENU].lh_Head; Node->ln_Succ; Node = Node->ln_Succ)
  1172.     {
  1173.      struct MenuNode *mn = (struct MenuNode *)Node;
  1174.      
  1175.      fprintf(f, "%s\n", Node->ln_Name);
  1176.      fprintf(f, "%s\n", mn->mn_Exec);
  1177.      fprintf(f, "%s\n", mn->mn_Sound);
  1178.     }
  1179.    fprintf(f, "---\n");
  1180.  
  1181.    fprintf(f, "Icon Objects\n");
  1182.    for(Node = ObjectLists[TMOBJTYPE_ICON].lh_Head; Node->ln_Succ; Node = Node->ln_Succ)
  1183.     {
  1184.      struct IconNode *in = (struct IconNode *)Node;
  1185.      
  1186.      fprintf(f, "%s\n", Node->ln_Name);
  1187.      fprintf(f, "%lu\n", in->in_Flags);
  1188.      fprintf(f, "%s\n%s\n%s\n", in->in_Exec, in->in_Image, in->in_Sound);
  1189.      fprintf(f, "%ld %ld\n", in->in_XPos, in->in_YPos);
  1190.     }
  1191.    fprintf(f, "---\n");
  1192.  
  1193.    fprintf(f, "Dock Objects\n");
  1194.    for(Node = ObjectLists[TMOBJTYPE_DOCK].lh_Head; Node->ln_Succ; Node = Node->ln_Succ)
  1195.     {
  1196.      struct DockNode *dn = (struct DockNode *)Node;
  1197.      struct Node     *node;
  1198.      
  1199.      fprintf(f, "%s\n", Node->ln_Name);
  1200.      fprintf(f, "%lu\n", dn->dn_Flags);
  1201.      fprintf(f, "%s\n%s\n%s\n", dn->dn_HotKey, dn->dn_PubScreen, dn->dn_Title);
  1202.      fprintf(f, "%s\n%u %u %u\n", dn->dn_Font.ta_Name, dn->dn_Font.ta_YSize,
  1203.                                  dn->dn_Font.ta_Style, dn->dn_Font.ta_Flags);
  1204.      fprintf(f, "%ld %ld\n", dn->dn_XPos, dn->dn_YPos);
  1205.      fprintf(f, "%lu\n", dn->dn_Columns);
  1206.  
  1207.      fprintf(f, "Tools\n");
  1208.      for(node = dn->dn_ToolsList->lh_Head; node->ln_Succ; node = node->ln_Succ)
  1209.       {
  1210.        struct ToolNode *tn = (struct ToolNode *)node;
  1211.  
  1212.        fprintf(f, "%s\n", node->ln_Name);
  1213.        fprintf(f, "%s\n%s\n", tn->tn_Image, tn->tn_Sound);
  1214.       }
  1215.      fprintf(f, "---\n");
  1216.     }
  1217.    fprintf(f, "---\n");
  1218.  
  1219.    fprintf(f, "Access Objects\n");
  1220.    for(Node = ObjectLists[TMOBJTYPE_ACCESS].lh_Head; Node->ln_Succ; Node = Node->ln_Succ)
  1221.     {
  1222.      struct AccessNode *an = (struct AccessNode *)Node;
  1223.      struct Node     *node;
  1224.      
  1225.      fprintf(f, "%s\n", Node->ln_Name);
  1226.      fprintf(f, "Entries\n");
  1227.      for(node = an->an_Entries.lh_Head; node->ln_Succ; node = node->ln_Succ)
  1228.       fprintf(f, "%s\n", node->ln_Name);
  1229.      fprintf(f, "---\n");
  1230.     }
  1231.    fprintf(f, "---\n");
  1232.  
  1233.    fclose(f);
  1234.   }
  1235.  else
  1236.   fprintf(stderr, "can't open %s\n", FileName);
  1237. }
  1238.  
  1239. char *AllocStr(char *s)
  1240. {
  1241.  int   len;
  1242.  char *Buffer, *t;
  1243.  
  1244.  t = s; len = 0;
  1245.  while ((*t != '\0') && (*t != '\n'))
  1246.   {
  1247.    t++;
  1248.    len++;
  1249.   }
  1250.  s[len] = '\0';
  1251.  
  1252.  if (len == 0)
  1253.   Buffer = NULL;
  1254.  else
  1255.   {
  1256.    Buffer = malloc(len+1);
  1257.    strcpy(Buffer, s);
  1258.   } 
  1259.  
  1260.  return Buffer;
  1261. }
  1262.  
  1263.  
  1264. #define MLEN 1024
  1265.  
  1266. void ReadAscii(char *FileName)
  1267. {
  1268.  FILE *f;
  1269.  
  1270.  if (f = fopen(FileName, "r"))
  1271.   {
  1272.    char s[MLEN];
  1273.  
  1274.    while (fgets(s, MLEN, f))
  1275.     {
  1276.      if (Stricmp(s, "Exec Objects\n") == 0)
  1277.       {
  1278.        struct ExecNode *en;
  1279.  
  1280.        fgets(s, MLEN, f);
  1281.        while (Stricmp(s, "---\n") != 0)
  1282.     {
  1283.      en = AllocMem(sizeof(struct ExecNode), MEMF_PUBLIC|MEMF_CLEAR);
  1284.      en->en_Node.ln_Name = AllocStr(s);
  1285.      fgets(s, MLEN, f);
  1286.      sscanf(s, "%lu %hd %hd %ld %lu\n", &en->en_Flags, &en->en_ExecType,
  1287.                                     &en->en_Priority, &en->en_Delay,
  1288.                                     &en->en_Stack);
  1289.      fgets(s, MLEN, f);
  1290.      en->en_Command = AllocStr(s);
  1291.      fgets(s, MLEN, f);
  1292.      en->en_CurrentDir = AllocStr(s);
  1293.      fgets(s, MLEN, f);
  1294.      en->en_HotKey = AllocStr(s);
  1295.      fgets(s, MLEN, f);
  1296.      en->en_Output = AllocStr(s);
  1297.      fgets(s, MLEN, f);
  1298.      en->en_Path = AllocStr(s);
  1299.      fgets(s, MLEN, f);
  1300.      en->en_PubScreen = AllocStr(s);
  1301.      fgets(s, MLEN, f);
  1302.  
  1303.      AddTail(&ObjectLists[TMOBJTYPE_EXEC], en);
  1304.     }
  1305.       }
  1306.      else if (Stricmp(s, "Image Objects\n") == 0)
  1307.       {
  1308.        struct ImageNode *in;
  1309.  
  1310.        fgets(s, MLEN, f);
  1311.        while (Stricmp(s, "---\n") != 0)
  1312.     {
  1313.      in = AllocMem(sizeof(struct ImageNode), MEMF_PUBLIC|MEMF_CLEAR);
  1314.      in->in_Node.ln_Name = AllocStr(s);
  1315.      fgets(s, MLEN, f);
  1316.      in->in_File = AllocStr(s);
  1317.      fgets(s, MLEN, f);
  1318.  
  1319.      AddTail(&ObjectLists[TMOBJTYPE_IMAGE], in);
  1320.     }
  1321.       }
  1322.      else if (Stricmp(s, "Sound Objects\n") == 0)
  1323.       {
  1324.        struct SoundNode *sn;
  1325.        
  1326.        fgets(s, MLEN, f);
  1327.        while (Stricmp(s, "---\n") != 0)
  1328.     {
  1329.      sn = AllocMem(sizeof(struct SoundNode), MEMF_PUBLIC|MEMF_CLEAR);
  1330.      sn->sn_Node.ln_Name = AllocStr(s);
  1331.      fgets(s, MLEN, f);
  1332.      sn->sn_Command = AllocStr(s);
  1333.      fgets(s, MLEN, f);
  1334.      sn->sn_Port = AllocStr(s);
  1335.      fgets(s, MLEN, f);
  1336.  
  1337.      AddTail(&ObjectLists[TMOBJTYPE_SOUND], sn);
  1338.     }
  1339.       }
  1340.      else if (Stricmp(s, "Menu Objects\n") == 0)
  1341.       {
  1342.        struct MenuNode *mn;
  1343.        
  1344.        fgets(s, MLEN, f);
  1345.        while (Stricmp(s, "---\n") != 0)
  1346.     {
  1347.      mn = AllocMem(sizeof(struct MenuNode), MEMF_PUBLIC|MEMF_CLEAR);
  1348.      mn->mn_Node.ln_Name = AllocStr(s);
  1349.      fgets(s, MLEN, f);
  1350.      mn->mn_Exec = AllocStr(s);
  1351.      fgets(s, MLEN, f);
  1352.      mn->mn_Sound = AllocStr(s);
  1353.      fgets(s, MLEN, f);
  1354.  
  1355.      AddTail(&ObjectLists[TMOBJTYPE_MENU], mn);
  1356.     }
  1357.       }
  1358.      else if (Stricmp(s, "Icon Objects\n") == 0)
  1359.       {
  1360.        struct IconNode *in;
  1361.  
  1362.        fgets(s, MLEN, f);
  1363.        while (Stricmp(s, "---\n") != 0)
  1364.     {
  1365.      in = AllocMem(sizeof(struct IconNode), MEMF_PUBLIC|MEMF_CLEAR);
  1366.      in->in_Node.ln_Name = AllocStr(s);
  1367.      fgets(s, MLEN, f);
  1368.      sscanf(s, "%lu\n", &in->in_Flags);
  1369.      fgets(s, MLEN, f);
  1370.      in->in_Exec = AllocStr(s);
  1371.      fgets(s, MLEN, f);
  1372.      in->in_Image = AllocStr(s);
  1373.      fgets(s, MLEN, f);
  1374.      in->in_Sound = AllocStr(s);
  1375.      fgets(s, MLEN, f);
  1376.      sscanf(s, "%ld %ld\n", &in->in_XPos, &in->in_YPos);
  1377.      fgets(s, MLEN, f);
  1378.  
  1379.      AddTail(&ObjectLists[TMOBJTYPE_ICON], in);
  1380.     }
  1381.       }
  1382.      else if (Stricmp(s, "Dock Objects\n") == 0)
  1383.       {
  1384.        struct DockNode *dn;
  1385.  
  1386.        fgets(s, MLEN, f);
  1387.        while (Stricmp(s, "---\n") != 0)
  1388.     {
  1389.      UWORD h1,h2;
  1390.  
  1391.      dn = AllocMem(sizeof(struct DockNode), MEMF_PUBLIC|MEMF_CLEAR);
  1392.      dn->dn_Node.ln_Name = AllocStr(s);
  1393.      fgets(s, MLEN, f);
  1394.      sscanf(s, "%lu\n", &dn->dn_Flags);
  1395.      fgets(s, MLEN, f);
  1396.      dn->dn_HotKey = AllocStr(s);
  1397.      fgets(s, MLEN, f);
  1398.      dn->dn_PubScreen = AllocStr(s);
  1399.      fgets(s, MLEN, f);
  1400.      dn->dn_Title = AllocStr(s);
  1401.      fgets(s, MLEN, f);
  1402.      dn->dn_Font.ta_Name = AllocStr(s);
  1403.      fgets(s, MLEN, f);
  1404.      sscanf(s, "%hu %hu %hu\n", &dn->dn_Font.ta_YSize, &h1, &h2);
  1405.      dn->dn_Font.ta_Style = h1;
  1406.      dn->dn_Font.ta_Flags = h2;
  1407.      dn->dn_FontDesc = NULL;
  1408.      fgets(s, MLEN, f);
  1409.      sscanf(s, "%ld %ld\n", &dn->dn_XPos, &dn->dn_YPos);
  1410.      fgets(s, MLEN, f);
  1411.      sscanf(s, "%lu\n", &dn->dn_Columns);
  1412.      fgets(s, MLEN, f);
  1413.      dn->dn_ToolsList = AllocMem(sizeof(struct List), MEMF_PUBLIC|MEMF_CLEAR);
  1414.      NewList(dn->dn_ToolsList);
  1415.      if (Stricmp(s, "Tools\n") == 0)
  1416.       {
  1417.        struct ToolNode *tn;
  1418.        
  1419.        fgets(s, MLEN, f);
  1420.        while (Stricmp(s, "---\n") != 0)
  1421.         {
  1422.          tn = AllocMem(sizeof(struct ToolNode), MEMF_PUBLIC|MEMF_CLEAR);
  1423.          tn->tn_Node.ln_Name = AllocStr(s);
  1424.          fgets(s, MLEN, f);
  1425.          tn->tn_Image = AllocStr(s);
  1426.          fgets(s, MLEN, f);
  1427.          tn->tn_Sound = AllocStr(s);
  1428.          fgets(s, MLEN, f);
  1429.  
  1430.          AddTail(dn->dn_ToolsList, tn);
  1431.         }
  1432.        fgets(s, MLEN, f);
  1433.       }
  1434.      else
  1435.       fprintf(stderr, "Error 2 : %s", s);
  1436.  
  1437.      AddTail(&ObjectLists[TMOBJTYPE_DOCK], dn);
  1438.     }
  1439.       }
  1440.      else if (Stricmp(s, "Access Objects\n") == 0)
  1441.       {
  1442.        struct AccessNode *an;
  1443.        
  1444.        fgets(s, MLEN, f);
  1445.        while (Stricmp(s, "---\n") != 0)
  1446.     {
  1447.      an = AllocMem(sizeof(struct AccessNode), MEMF_PUBLIC|MEMF_CLEAR);
  1448.      an->an_Node.ln_Name = AllocStr(s);
  1449.      fgets(s, MLEN, f);
  1450.      NewList(&an->an_Entries);
  1451.      if (Stricmp(s, "Entries\n") == 0)
  1452.       {
  1453.        struct Node *node;
  1454.  
  1455.        fgets(s, MLEN, f);
  1456.        while (Stricmp(s, "---\n") != 0)
  1457.         {
  1458.          node = AllocMem(sizeof(struct Node), MEMF_PUBLIC|MEMF_CLEAR);
  1459.          node->ln_Name = AllocStr(s);
  1460.          fgets(s, MLEN, f);
  1461.  
  1462.          AddTail(&an->an_Entries, node);
  1463.         }
  1464.        fgets(s, MLEN, f);
  1465.       }
  1466.      else
  1467.       fprintf(stderr, "Error 3 : %s", s);
  1468.      
  1469.      AddTail(&ObjectLists[TMOBJTYPE_ACCESS], an);
  1470.     }
  1471.       }
  1472.      else
  1473.       fprintf(stderr, "Error 1 : %s", s);
  1474.     }
  1475.  
  1476.    fclose(f);
  1477.   }
  1478.  else
  1479.   fprintf(stderr, "can't open %s\n", FileName);
  1480. }
  1481.  
  1482.  
  1483. #define TMPrefs   (char *)ArgArray[0]
  1484. #define TMAscii   (char *)ArgArray[1]
  1485. #define WriteFlag (BOOL)  ArgArray[2]
  1486.  
  1487. void main(int argc, char *argv[])
  1488. {
  1489.  struct RDArgs     *rd;
  1490.  ULONG              ArgArray[3];
  1491.  ULONG              rc = NULL;
  1492.  char               Template[] = "TMPrefs/A,TMAscii/A,WRITE/S";
  1493.  
  1494.  if (argc == 0)
  1495.   {
  1496.    printf("TM2Ascii cannot run from WorkBench !!\n");
  1497.    printf("Please use CLI instead\n");
  1498.   }
  1499.  else
  1500.   {
  1501.    ArgArray[0] = NULL;
  1502.    ArgArray[1] = NULL;
  1503.    ArgArray[2] = FALSE;
  1504.    
  1505.    rd = ReadArgs(Template, ArgArray, NULL);
  1506.    
  1507.    if (rd)
  1508.     {
  1509.      BPTR lock;
  1510.      int  i;
  1511.      
  1512.      for (i=0; i<TMOBJTYPES; i++) NewList(&ObjectLists[i]);
  1513.      
  1514.      if (WriteFlag)
  1515.       if (lock = Lock(TMAscii, ACCESS_READ))
  1516.        {
  1517.     UnLock(lock);
  1518.     
  1519.     ReadAscii(TMAscii);
  1520.     WriteConfigFile(TMPrefs);
  1521.        }
  1522.       else
  1523.        {
  1524.     PrintFault(205, TMAscii); SetIoErr(205);
  1525.     rc = 20;
  1526.        }
  1527.      else
  1528.       if (lock = Lock(TMPrefs, ACCESS_READ))
  1529.        {
  1530.     UnLock(lock);
  1531.     
  1532.     ReadConfigFile(TMPrefs);
  1533.     WriteAscii(TMAscii);
  1534.        }
  1535.       else
  1536.        {
  1537.     PrintFault(205, TMPrefs); SetIoErr(205);
  1538.     rc = 20;
  1539.        }
  1540.      
  1541.      FreeAllObjects();
  1542.     }
  1543.    else
  1544.     {
  1545.      PrintFault(116, "");
  1546.      SetIoErr(116);
  1547.      rc = 20;
  1548.     }
  1549.    if (rd) FreeArgs(rd);
  1550.  
  1551.    exit(rc);
  1552.   }
  1553. }
  1554.